﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;
using DevExpress.XtraBars;
using DevExpress.XtraEditors;
using ProgramMain.Classifiers;
using ProgramMain.Database;
using ProgramMain.Database.SimpleOpticNetDBTableAdapters;
using ProgramMain.Framework;
using ProgramMain.Google;
using ProgramMain.Layers;
using ProgramMain.NetVis;

namespace ProgramMain.OpticNet
{
    public partial class VertexMapCtl : ProgramMain.Framework.BaseDetailCtl
    {
        private const ExtendedPropertieTypes CurveElements = ExtendedPropertieTypes.VertexCurveElementAll;

        public VertexMapCtl()
        {
            InitializeComponent();

            visLayer = new VisLayer() { PlanType = 3 };
            visLayer.PlanCommit += new EventHandler(visLayer_PlanCommit);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            SetStyle(ControlStyles.Opaque, true);
            VertexState = VertexMapState.None;
            this.MouseWheel += new MouseEventHandler(VertexMapCtl_MouseWheel);

        }

        public string VertexCaption { get; set; }
        public string VertexAdres { get; set; }
        public void ReDrawMap()
        {
            visLayer.DrawVertex(new Rectangle(this.Location, this.Size), false);
        }
        private Layers.VisLayer visLayer;

        private bool IsPopupShow = false;

        private Point StartMovePoint = Point.Empty;

        private RangeBase _popupRange;

        public VertexMapState VertexState { get; set; }

        public event EventHandler<IntEvent> BeforeVertexJump;

        private enum TMoveType { None, MovePlan, MoveEquipment }

        private TMoveType _moveType = TMoveType.None;

        public bool AllConnection
        {
            set
            {
                visLayer.AllConnection = value;
                visLayer.DrawVertex(new Rectangle(this.Location, this.Size), false);
            }
        }

        public int PlanType
        {
            set
            {
                visLayer.PlanType = value;
                LoadData();
                if (RefreshVertex != null) RefreshVertex(this, new IntEvent(null));
                this.Invalidate();
            }
        }

        private void LoadElement(ExtendedPropertieTypes extendedPropertieTypes, bool isLoad)
        {
            //прочитать данные из базы и заполнить датасет
            this.extendedPropertiesTableAdapter.SelectCommandTimeout = ProgramMain.Properties.Settings.Default.LongQueryTimeout;
            this.extendedPropertiesTableAdapter.Fill(this.simpleOpticNetDB.tblExtendedProperties, (int)extendedPropertieTypes,
                                                     DetailID);
            propertySource.MoveFirst();
            if (isLoad)
            {
                string xml = string.Empty;
                if (this.propertySource.Current != null)
                {
                    SimpleOpticNetDB.tblExtendedPropertiesRow row =
                        (SimpleOpticNetDB.tblExtendedPropertiesRow)((DataRowView)propertySource.Current).Row;
                    xml = row.Property;

                }

                switch (extendedPropertieTypes)
                {
                    case ExtendedPropertieTypes.VertexCurveElementAll:
                        visLayer.DeSerializeVertex(xml);
                        break;
                    case ExtendedPropertieTypes.VertexConnectionLineAll:
                        visLayer.DeSerializeLineConnection(xml);
                        break;
                    case ExtendedPropertieTypes.VertexCurveElementOnlyCable:
                        visLayer.DeSerializeVertex(xml);
                        break;
                    case ExtendedPropertieTypes.VertexConnectionLineOnlyCable:
                        visLayer.DeSerializeLineConnection(xml);
                        break;
                    case ExtendedPropertieTypes.VertexCurveElementOnlyCableBox:
                        visLayer.DeSerializeVertex(xml);
                        break;
                    case ExtendedPropertieTypes.VertexConnectionLineOnlyCableBox:
                        visLayer.DeSerializeLineConnection(xml);
                        break;
                }
            }
        }

        protected override void LoadData()
        {
            if (visLayer == null) return;
            switch (visLayer.PlanType)
            {
                case 3:
                    LoadElement(ExtendedPropertieTypes.VertexCurveElementAll, true);
                    LoadElement(ExtendedPropertieTypes.VertexConnectionLineAll, true);
                    break;
                case 2:
                    LoadElement(ExtendedPropertieTypes.VertexCurveElementOnlyCableBox, true);
                    LoadElement(ExtendedPropertieTypes.VertexConnectionLineOnlyCableBox, true);
                    break;
                case 1:
                    LoadElement(ExtendedPropertieTypes.VertexCurveElementOnlyCable, true);
                    LoadElement(ExtendedPropertieTypes.VertexConnectionLineOnlyCable, true);
                    break;
            }
        }

        private void SaveVertex()
        {
            if (visLayer == null) return;
            switch (visLayer.PlanType)
            {
                case 3:
                    SaveProperty(visLayer.SerializeVertex(), ExtendedPropertieTypes.VertexCurveElementAll);
                    SaveProperty(visLayer.SerializeLineConnection(), ExtendedPropertieTypes.VertexConnectionLineAll);
                    break;
                case 2:
                    SaveProperty(visLayer.SerializeVertex(), ExtendedPropertieTypes.VertexCurveElementOnlyCableBox);
                    SaveProperty(visLayer.SerializeLineConnection(), ExtendedPropertieTypes.VertexConnectionLineOnlyCableBox);
                    break;
                case 1:
                    SaveProperty(visLayer.SerializeVertex(), ExtendedPropertieTypes.VertexCurveElementOnlyCable);
                    SaveProperty(visLayer.SerializeLineConnection(), ExtendedPropertieTypes.VertexConnectionLineOnlyCable);
                    break;
            }
        }

        private void DeleteLine()
        {
            if (visLayer == null) return;
            switch (visLayer.PlanType)
            {
                case 3:
                    SaveProperty("", ExtendedPropertieTypes.VertexConnectionLineAll);
                    break;
                case 2:
                    SaveProperty("", ExtendedPropertieTypes.VertexConnectionLineOnlyCableBox);
                    break;
                case 1:
                    SaveProperty("", ExtendedPropertieTypes.VertexConnectionLineOnlyCable);
                    break;
            }
        }

        private void SaveProperty(string property, ExtendedPropertieTypes extendedPropertieTypes)
        {
            if (!CheckSecurityEditAction())
                return;
            LoadElement(extendedPropertieTypes, true);
            if (this.propertySource.Current != null)
            {
                SimpleOpticNetDB.tblExtendedPropertiesRow row =
                    (SimpleOpticNetDB.tblExtendedPropertiesRow)((DataRowView)propertySource.Current).Row;
                row.Property = property;
                propertySource.EndEdit();
            }
            else
            {
                if (DetailID.HasValue)
                {
                    propertySource.AddNew();
                    SimpleOpticNetDB.tblExtendedPropertiesRow row =
                        (SimpleOpticNetDB.tblExtendedPropertiesRow)((DataRowView)propertySource.Current).Row;
                    row.Property = property;
                    row.ObjectID = DetailID.Value;
                    row.TypeID = (int)extendedPropertieTypes;
                    propertySource.EndEdit();
                }
            }
            this.extendedPropertiesTableAdapter.SelectCommandTimeout =
                ProgramMain.Properties.Settings.Default.LongQueryTimeout;
            this.extendedPropertiesTableAdapter.Update(this.simpleOpticNetDB.tblExtendedProperties);

        }

        public event EventHandler<IntEvent> ZoomChanged;

        public void SetZoom(int zoom)
        {
            if (visLayer != null) visLayer.SetZoom(zoom);
            //   visLayer.DrawVertex();
            SetScrollLimit();

        }
        private void SetScrollLimit()
        {
            Rectangle r = visLayer.GetPlanRectangle();

            widthScroll.Minimum = 0 - r.Width;
            widthScroll.Maximum = r.Width;

            heightScroll.Minimum = 0 - r.Height;
            heightScroll.Maximum = r.Height;

        }

        void visLayer_PlanCommit(object sender, EventArgs e)
        {
            this.Invalidate();
        }

        void VertexMapCtl_MouseWheel(object sender, MouseEventArgs e)
        {
            if (e.Delta != 0 && ZoomChanged != null)
            {
                ZoomChanged(this, new IntEvent(e.Delta > 0 ? 1 : -1));
            }
        }

        private void StartConnection(Point mousePoint)
        {
            if (!CheckSecurityEditAction(false)) return;

            List<RangeBase> ranges = visLayer.FindRange(mousePoint);
            if (ranges.Count == 0) return;

            FibreRange fibre = ranges[0] as FibreRange;
            if (fibre != null)
            {
                fibre.Status = RangeStatus.CreateConnection;

                MapDragObject.StartExistingFibreDragDrop(this, mousePoint, fibre.RangeID);
            }

        }

        private void CreateConnection(Point mousePoint, int StartFibreID)
        {
            if (!CheckSecurityEditAction(false)) return;

            List<RangeBase> ranges = visLayer.FindRange(mousePoint);
            if (ranges.Count == 0) return;
            FibreRange fibre2 = ranges[0] as FibreRange;

            List<RangeBase> rangesByID = visLayer.FindRangeByRangeID(StartFibreID);// visLayer.FindRangeByFibreID(StartFibreID, true);
            if (rangesByID.Count == 0) return;
            FibreRange StartFibre = rangesByID[0] as FibreRange;
            if (fibre2 != null && StartFibre != null && DetailID.HasValue)
            {
                if (new FibrePointList().AddFibrePoint(StartFibre.FibreID, fibre2.FibreID, DetailID.Value))
                {
                    visLayer.CreateFibreLine(StartFibre, fibre2, true, false);
                    SaveVertex();
                    LoadData();
                    if (RefreshVertex != null) RefreshVertex(this, new IntEvent(null));
                }
            }

        }

        void VertexMapCtl_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            List<RangeBase> ranges = visLayer.FindRange(e.Location);
            if (ranges.Count > 0)
            {
                _popupRange = ranges[0];
                if (_popupRange != null && _popupRange is FibreRange)
                {
                    ToVertex_ItemClick(sender, null);
                }

                if (_popupRange != null && _popupRange is BodyRange)
                {
                    BodyRange body = (BodyRange)_popupRange;
                    if (body.Equip != null)
                    {
                        if (body.bodyType == BodyType.Cross)
                        {
                            FrmFibrePointDetail fibrePointDetail = new FrmFibrePointDetail();
                            fibrePointDetail.VertexID = body.Equip.Row.VertexID;
                            fibrePointDetail.EquipVertexID = body.Equip.Row.ID;
                            fibrePointDetail.ShowForm();
                        }

                        if (body.bodyType == BodyType.CableBox)
                            try
                            {
                                CableBoxVis cableBoxVis = (CableBoxVis)body.Equip;
                                FrmFibrePointDetail fibrePointDetail = new FrmFibrePointDetail();
                                fibrePointDetail.VertexID = cableBoxVis.Row.VertexID;
                                fibrePointDetail.EquipVertexID = cableBoxVis.Row.ID;
                                fibrePointDetail.ShowForm();
                            }
                            catch (Exception)
                            {
                            }
                    }
                }
            }
        }

        void VertexMapCtl_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Left && e.Button != MouseButtons.Right) return;
            StartMovePoint = e.Location;
            if (e.Button == MouseButtons.Left)
            {
                List<RangeBase> ranges = visLayer.FindRange(e.Location);
                if (ranges.Count == 0) _moveType = TMoveType.MovePlan;
                else _moveType = TMoveType.MoveEquipment;

                if (VertexState == VertexMapState.None)
                {
                    if (ranges.Count > 0)
                    {
                        visLayer.ClearConnecion();
                        List<RangeBase> rangesActive = visLayer.GetRangeActive();
                        for (int i = 0; i < rangesActive.Count; i++)
                        {
                            rangesActive[i].Status = RangeStatus.Connection;
                        }
                        RangeBase item = ranges[0];

                        if (item is FibreRange)
                        {
                            visLayer.ConnectOut((FibreRange)item, true);
                        }

                    }
                }
                else if (VertexState == VertexMapState.Connection)
                {
                    StartConnection(e.Location);
                    //   
                }
                visLayer.DrawVertex(new Rectangle(this.Location, this.Size), false);
            }
            else if (e.Button == MouseButtons.Right)
            {
                List<RangeBase> ranges = visLayer.FindRange(e.Location);
                if (ranges.Count == 1)
                {
                    _popupRange = ranges[0];
                    if (_popupRange != null && _popupRange is FibreRange)
                        popupFibre.ShowPopup(MousePosition);
                    if (_popupRange != null && _popupRange is SectionConnectionRange)
                        popupSection.ShowPopup(MousePosition);
                    if (_popupRange != null && _popupRange is BodyRange)
                    {
                        BodyRange bodyRange = (BodyRange)_popupRange;
                        if (bodyRange.Equip != null)
                        {

                            barView.Visibility = DevExpress.XtraBars.BarItemVisibility.Always;
                            switch (bodyRange.Equip.CurveElementKindID)
                            {
                                case 1:
                                    barView.Caption = "Детализация";
                                    break;
                                case 2:
                                    barView.Caption = "Детализация";
                                    break;
                                case 3:
                                    barView.Caption = "Детализация";
                                    break;
                            }
                        }
                        else
                            barView.Visibility = DevExpress.XtraBars.BarItemVisibility.Never;
                        popupBody.ShowPopup(MousePosition);
                    }

                }
                if (ranges.Count == 0)
                {
                    popupAdd.ShowPopup(MousePosition);
                }
            }
        }

        private void CableToCable(int cable1ID, int cable2ID)
        {
            if (!DetailID.HasValue) return;
            SelectFibreAutoConnectCtl dialog = new SelectFibreAutoConnectCtl();
            dialog.Cable1ID = cable1ID;
            dialog.Cable2ID = cable2ID;
            DialogResult dlgRes = dialog.ShowModal(BaseModalDetailCtl.ShowModeTypes.Edit);
            if (dlgRes == DialogResult.OK && dialog.FibreMaxCount.HasValue)
                try
                {
                    string caption = "Муфта";
                    int? newCurveElementID = new CableBoxList().AddCableBox(DetailID.Value, dialog.FibreMaxCount.Value, caption);
                    if (!newCurveElementID.HasValue) return;

                    visLayer.CreateCableBox(newCurveElementID);
                    CrossBoxVis newCurveElement = visLayer.FindCurveElementByID(newCurveElementID.Value);
                    newCurveElement.CreateFibre(DetailID.Value);

                    CrossBoxVis cable1 = visLayer.FindCurveElementByID(cable1ID);
                    CrossBoxVis cable2 = visLayer.FindCurveElementByID(cable2ID);

                    int mf = 1;
                    //    FibrePointList pointList = new FibrePointList();
                    for (int i = dialog.start1; i < dialog.finish1 + 1; i++)
                    {
                        SimpleOpticNetDB.FibreRow cableBoxFibre =
                            (from q in newCurveElement.Fibres.Cast<SimpleOpticNetDB.FibreRow>()
                             where q.Number == mf
                             select q).First();

                        SimpleOpticNetDB.FibreRow cable1Fibre =
                           (from q in cable1.Fibres.Cast<SimpleOpticNetDB.FibreRow>()
                            where q.Number == i
                            select q).First();

                        SimpleOpticNetDB.FibreRow cable2Fibre =
                           (from q in cable2.Fibres.Cast<SimpleOpticNetDB.FibreRow>()
                            where q.Number == dialog.start2
                            select q).First();

                        new FibrePointList().AddFibrePoint(cableBoxFibre.ID, cable1Fibre.ID, DetailID.Value);
                        new FibrePointList().AddFibrePoint(cableBoxFibre.ID, cable2Fibre.ID, DetailID.Value);
                        mf++;
                        dialog.start2++;
                    }
                }
                catch (Exception)
                {
                }

        }

        public void CreateAutoConnect()
        {
            CableBoxesTableAdapter cableBoxesAdapter = new CableBoxesTableAdapter();
            cableBoxesAdapter.ClearBeforeFill = true;
            cableBoxesAdapter.SelectCommandTimeout = Properties.Settings.Default.LongQueryTimeout;
            SimpleOpticNetDB.CableBoxesDataTable CableBoxes = cableBoxesAdapter.GetData(null, DetailID, 2);

            EquipmentTableAdapter equipmentTableAdapter = new EquipmentTableAdapter();
            equipmentTableAdapter.ClearBeforeFill = true;
            equipmentTableAdapter.SelectCommandTimeout = Properties.Settings.Default.LongQueryTimeout;
            SimpleOpticNetDB.EquipmentDataTable equipmentDataTable = equipmentTableAdapter.GetData(DetailID, null);

            List<CrossBoxVis> cables = visLayer.GetEquipmentByKindID(1);
            if (cables.Count == 2 && CableBoxes.Count == 0 && equipmentDataTable.Count == 0)
            {
                if (
                    XtraMessageBox.Show("Разварить кабеля автоматически?", "Сообщение", MessageBoxButtons.YesNo,
                                        MessageBoxIcon.Exclamation) == DialogResult.Yes
                    && Framework.BaseSecurity.CheckSecurityTechAction())
                {
                    CableToCable(cables[0].ID, cables[1].ID);
                    if (RefreshVertex != null) RefreshVertex(this, new IntEvent(null));
                }
            }
        }

        public void RefreshControl(int? fibreID)
        {
            visLayer.SetGraphic(DetailID);

        }

        public void VertexMapCtl_DetailIDChanged(object sender, DetailEventArgs e)
        {
            LoadData();
            RefreshControl(null);

        }

        private int? _rangeId = null;

        public void VertexMapCtl_MouseMove(object sender, MouseEventArgs e)
        {
            if (StartMovePoint != Point.Empty)
                try
                {
                    List<RangeBase> ranges = visLayer.FindRange(StartMovePoint);
                    if (ranges.Count == 0 && _moveType == TMoveType.MovePlan)
                    {
                        heightScroll.Value += StartMovePoint.Y - e.Y;
                        widthScroll.Value += StartMovePoint.X - e.X;
                        StartMovePoint = e.Location;
                    }
                    else
                    {
                        RangeBase item = ranges[0];
                        if (_moveType == TMoveType.MoveEquipment)
                        {
                            int x = (int)((e.X - StartMovePoint.X) / visLayer.Scale);
                            int y = (int)((e.Y - StartMovePoint.Y) / visLayer.Scale);
                            if (x != 0 || y != 0)
                            {
                                if (Framework.BaseSecurity.CheckSecurityTechAction())
                                {
                                    System.Drawing.Size s = new Size(x, y);
                                    if (item.Shift(s))
                                    {
                                    }
                                    visLayer.DrawVertex(new Rectangle(this.Location, this.Size), false);
                                    StartMovePoint = e.Location;
                                }
                                else
                                {
                                    _moveType = TMoveType.None;
                                }
                            }
                        }
                    }

                }
                catch (Exception)
                { }
            #region Hint
            {
                List<RangeBase> ranges = visLayer.FindRange(e.Location);
                if (ranges.Count > 0)
                {

                    Bitmap bitmap = Properties.Resources.router_24;
                    RangeBase item = ranges[0];
                    if (!string.IsNullOrEmpty(item.Hint) && (!_rangeId.HasValue || (_rangeId.HasValue && _rangeId.Value != item.RangeID)))
                    {
                        _rangeId = item.RangeID;
                        toolTip1.InitialDelay = 10000;
                        toolTip1.SetToolTip(this, item.Hint.Replace("***", "\n"));
                    }
                    if (item is DiamondRange || item is BodyRange) this.Cursor = Cursors.SizeAll;
                    if (item is SectionConnectionRange)
                    {
                        SectionConnectionRange s = (SectionConnectionRange)item;
                        if (s.StaticPoint == 0 && s.PositionState == SectionConnectionRange.Position.Horizontal) this.Cursor = Cursors.SizeNS;
                        if (s.StaticPoint == 0 && s.PositionState == SectionConnectionRange.Position.Vertical) this.Cursor = Cursors.SizeWE;
                        if (s.StaticPoint == 0 && s.PositionState == SectionConnectionRange.Position.Entity) this.Cursor = Cursors.SizeAll;
                    }
                }
                else
                {
                    this.Cursor = Cursors.Default;
                    _rangeId = null;
                    toolTip1.Hide(this);
                }
            }

            #endregion
        }

        public void Priting()
        {
            System.Drawing.Printing.PrintDocument print = new System.Drawing.Printing.PrintDocument();
            print.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(print_PrintPage);
            print.DefaultPageSettings.Landscape = true;

            print.Print();
        }

        private Bitmap _printCaption(int Width)
        {
            Bitmap b = new Bitmap(Width, 20);

            Font font = new Font("Arial", 9, FontStyle.Regular);
            Graphics graphics = Graphics.FromImage(b);

            graphics.FillRectangle(Brushes.White, 0, 0, Width, 20);
            Brush brush = Brushes.Black;
            graphics.DrawString(string.Format("{0}  - ({1})", VertexCaption, VertexAdres), font, brush, new Point(0, 0));
            return b;
        }

        void print_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
        {
            if (visLayer.Plan != null)
            {
                Bitmap caption = _printCaption(500);
                Rectangle r = visLayer.GetPlanRectangle();
                Point p = new Point(5, 3);
                e.Graphics.DrawImage(caption, p);
                p = new Point(-1 * r.Location.X, -1 * r.Location.Y) + new Size(5, caption.Size.Height + 5);
                e.Graphics.DrawImage(visLayer.Plan, p);
            }
        }

        private void VertexMapCtl_Paint(object sender, PaintEventArgs e)
        {

            if (visLayer.Plan != null) e.Graphics.DrawImage(visLayer.Plan, 0, 0);
            else
            {
                visLayer.PlanToCenter(new Point(this.Size.Width / 2, this.Size.Height / 2));
                SetScrollLimit();

                //heightScroll.Value = visLayer.ZeroPoint.Y;
                //widthScroll.Value = visLayer.ZeroPoint.X;
                //HashPointSift = visLayer.ZeroPoint;

                this.heightScroll.ValueChanged += new System.EventHandler(this.Scroll_ValueChanged);
                this.widthScroll.ValueChanged += new System.EventHandler(this.Scroll_ValueChanged);
                visLayer.DrawVertex(new Rectangle(this.Location, this.Size), false);
            }

        }

        private void VertexMapCtl_Load(object sender, EventArgs e)
        {

        }

        private void ToVertex_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            int? VertexID = _popupRange.ObjectID();
            if (VertexID.HasValue)
            {
                if (BeforeVertexJump != null) BeforeVertexJump(this, new IntEvent(VertexID));
            }
        }

        private void barCreatePath_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            //int fibre_id = 0;
            if (_popupRange is FibreRange)
            {
                FibreRange fibreRange = (FibreRange)_popupRange;
                if (fibreRange.Row != null)
                {
                    int fibre_id = fibreRange.Row.ID;
                    FrmVertexes frmVertexes = FrmVertexes.ShowForm();
                    frmVertexes.SetPath(fibre_id);
                }
            }
        }

        private SimpleOpticNetDB.VertexesDataTable GetPathTerminator()
        {
            if (_popupRange is FibreRange)
            {
                FibreRange fibreRange = (FibreRange)_popupRange;
                if (fibreRange.Row != null)
                {
                    int fibre_id = fibreRange.Row.ID;
                    VertexesTableAdapter adapter = new VertexesTableAdapter();
                    adapter.ClearBeforeFill = true;
                    adapter.SelectCommandTimeout = Properties.Settings.Default.LongQueryTimeout;
                    return adapter.GetData(null, null, null, null, null, null, fibre_id, true, null);
                }
                return null;
            }
            return null;
        }

        private void barToEnd_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
        {
            SimpleOpticNetDB.VertexesDataTable vertexDBRows = GetPathTerminator();
            if (vertexDBRows != null && vertexDBRows.Count > 1)
            {
                if (BeforeVertexJump != null) BeforeVertexJump(this, new IntEvent(vertexDBRows[1].ID));
            }
        }

        private void barToFirst_ItemClick(object sender, ItemClickEventArgs e)
        {
            SimpleOpticNetDB.VertexesDataTable vertexDBRows = GetPathTerminator();
            if (vertexDBRows != null && vertexDBRows.Count > 1)
            {
                if (BeforeVertexJump != null) BeforeVertexJump(this, new IntEvent(vertexDBRows[0].ID));
            }
        }

        private Point HashPointSift = Point.Empty;
        private void Scroll_ValueChanged(object sender, EventArgs e)
        {
            Size shift = new Size(HashPointSift.X - widthScroll.Value, HashPointSift.Y - heightScroll.Value);
            if (shift != System.Drawing.Size.Empty)
            {
                visLayer.ZeroPoint += shift;
                visLayer.DrawVertex(new Rectangle(this.Location, this.Size), false);
            }
            HashPointSift.X = widthScroll.Value;
            HashPointSift.Y = heightScroll.Value;
        }

        private void VertexMapCtl_DragEnter(object sender, DragEventArgs e)
        {
            try
            {
                MapDragObject dragObject = MapDragObject.GetObject(this, e);
                if (dragObject != null && dragObject.DragObjectType == MapDragObject.DragObjectTypes.Fibre)
                {
                    e.Effect = dragObject.DragDropAction;
                }
                else
                {
                    e.Effect = DragDropEffects.None;
                }
            }
            catch (Exception)
            {
                e.Effect = DragDropEffects.None;
            }
        }

        private void VertexMapCtl_GiveFeedback(object sender, GiveFeedbackEventArgs e)
        {
            MapDragObject.ChangeCursor(e, MapDragObject.DragObjectTypes.Fibre);
        }

        private void VertexMapCtl_DragDrop(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.None;
            Cursor.Current = Cursors.Default;

            MapDragObject dragObject = MapDragObject.GetObject(this, e);

            if (dragObject != null && dragObject.DragObjectType == MapDragObject.DragObjectTypes.Fibre)
            {
                if (dragObject.DragDropAction == DragDropEffects.Move)
                {
                    CreateConnection(dragObject.EndPoint, dragObject.ObjectID);
                }
            }
        }

        private void VertexMapCtl_MouseUp(object sender, MouseEventArgs e)
        {
            List<RangeBase> ranges = visLayer.FindRange(StartMovePoint);
            if (ranges.Count > 0)
            {
                SaveVertex();
                LoadData();
            }
            if (!IsPopupShow) StartMovePoint = Point.Empty;
            _moveType = TMoveType.None;

        }

        public event EventHandler<IntEvent> RefreshVertex;

        private void DelConnect_ItemClick(object sender, ItemClickEventArgs e)
        {
            if (!Framework.BaseSecurity.CheckSecurityTechAction()) return;
            if (_popupRange is FibreRange)
            {
                FibreRange fibreRange = (FibreRange)_popupRange;
                if (fibreRange.ToFibreID.HasValue && this.DetailID.HasValue)
                {
                    if (visLayer.PlanType == 3)
                        new FibrePointList()
                            {
                                FibreINID = fibreRange.FibreID,
                                FibreOutID = fibreRange.ToFibreID,
                                VertexID = this.DetailID.Value,
                                DetailID = fibreRange.CurveElementID,
                                AutoClose = false
                            }.DeleteConnection(visLayer.PlanType);
                    if (visLayer.PlanType == 1)
                        try
                        {
                            new FibrePointList() { FibreINID = fibreRange.FibreID, VertexID = this.DetailID.Value, DetailID = fibreRange.CurveElementID, AutoClose = false }.DeleteConnection(visLayer.PlanType);
                            fibreRange = visLayer.FindRangeByFibreID(fibreRange.ToFibreID.Value, false)[0] as FibreRange;
                            if (fibreRange != null)
                                new FibrePointList() { FibreINID = fibreRange.FibreID, VertexID = this.DetailID.Value, DetailID = fibreRange.CurveElementID, AutoClose = true }.DeleteConnection(visLayer.PlanType);
                        }
                        catch (Exception)
                        { }
                    SaveVertex();
                    LoadData();
                    if (RefreshVertex != null) RefreshVertex(this, new IntEvent(null));
                    visLayer.DrawVertex(new Rectangle(this.Location, this.Size), false);
                }
            }
        }

        private void VertexMapCtl_Leave(object sender, EventArgs e)
        {

        }

        private void barCreatePathMap_ItemClick(object sender, ItemClickEventArgs e)
        {
            if (_popupRange is FibreRange)
            {
                FrmOpticMap map = FrmOpticMap.ShowForm();
                map.ClearLighted();
                try
                {
                    VertexesTableAdapter vertexesTableAdapter = new VertexesTableAdapter();
                    vertexesTableAdapter.ClearBeforeFill = true;
                    vertexesTableAdapter.SelectCommandTimeout = Properties.Settings.Default.LongQueryTimeout;
                    SimpleOpticNetDB.VertexesDataTable vertexesDataTable = vertexesTableAdapter.GetData(null, null, null,
                                                                                                        null,
                                                                                                        null, null,
                                                                                                        _popupRange.
                                                                                                            FibreID,
                                                                                                        false, null);

                    SimpleOpticNetDB.VertexesRow v =
                        (from q in vertexesDataTable.Cast<SimpleOpticNetDB.VertexesRow>()
                         where q.ID == DetailID
                         select q).First();

                    map.SetCenterMapObject(v.Longitude, v.Latitude);
                    foreach (SimpleOpticNetDB.VertexesRow item in vertexesDataTable.Cast<SimpleOpticNetDB.VertexesRow>()
                        )
                    {
                        map.AddVertesLighted(item.ID);
                    }
                }
                catch (Exception)
                {
                }

                CableTunnelsTableAdapter cableTunnelsTableAdapter = new CableTunnelsTableAdapter();
                cableTunnelsTableAdapter.ClearBeforeFill = true;
                cableTunnelsTableAdapter.SelectCommandTimeout = Properties.Settings.Default.LongQueryTimeout;
                SimpleOpticNetDB.CableTunnelsDataTable cableTunnelsDataTable = cableTunnelsTableAdapter.GetData(null, null, null, null, null, null, _popupRange.FibreID, null, null);

                foreach (SimpleOpticNetDB.CableTunnelsRow item in cableTunnelsDataTable)
                {
                    map.AddCableTunnelLighted(item.ID);
                }
            }
        }

        private void AddCableBox_ItemClick(object sender, ItemClickEventArgs e)
        {
            if (!Framework.BaseSecurity.CheckSecurityTechAction()) return;
            if (DetailID.HasValue)
            {
                new CableBoxList() { CableBoxKind = CableBoxKinds.CableBox }.AddCableBox(DetailID.Value);
                if (RefreshVertex != null) RefreshVertex(this, new IntEvent(null));
                visLayer.DrawVertex(new Rectangle(this.Location, this.Size), false);
            }
        }

        private void AddCross_ItemClick(object sender, ItemClickEventArgs e)
        {
            if (!Framework.BaseSecurity.CheckSecurityTechAction()) return;
            if (DetailID.HasValue)
            {
                new EquipmentList().AddEquipment(DetailID.Value);
                if (RefreshVertex != null) RefreshVertex(this, new IntEvent(null));
                visLayer.DrawVertex(new Rectangle(this.Location, this.Size), false);
            }
        }

        private void CurveElementDelete_ItemClick(object sender, ItemClickEventArgs e)
        {
            if (!Framework.BaseSecurity.CheckSecurityTechAction()) return;
            if (_popupRange is BodyRange)
            {
                BodyRange body = (BodyRange)_popupRange;
                if (body.Equip != null)
                {
                    if (body.Equip.CurveElementKindID == 2 || body.Equip.CurveElementKindID == 4)
                        CableBoxDelete(body.Equip.ID);
                    if (body.Equip.CurveElementKindID == 3)
                        CrossDelete(body.Equip.ID);
                    visLayer.DrawVertex(new Rectangle(this.Location, this.Size), false);
                }
            }
        }

        private void CableBoxDelete(int id)
        {
            CableBoxList cableBoxList = new CableBoxList();
            cableBoxList.Present = PresentFormType.InCableBoxes;
            cableBoxList.DetailID = id;
            cableBoxList.DBRead();
            cableBoxList.DeleteCableBox();
            if (RefreshVertex != null) RefreshVertex(this, new IntEvent(null));
        }

        private void CrossDelete(int id)
        {
            EquipmentList equipmentList = new EquipmentList();
            equipmentList.Present = PresentFormType.InEquipment;
            equipmentList.EquipID = id;
            equipmentList.DetailID = DetailID;
            equipmentList.DeleteEquipment();
            if (RefreshVertex != null) RefreshVertex(this, new IntEvent(null));


        }

        private void barTurn_ItemClick(object sender, ItemClickEventArgs e)
        {
            if (!Framework.BaseSecurity.CheckSecurityTechAction()) return;
            if (_popupRange is BodyRange)
            {
                BodyRange bodyRange = (BodyRange)_popupRange;
                if (bodyRange.Equip != null)
                {
                    bodyRange.Equip.Enter = bodyRange.Equip.Enter == 1 ? 2 : 1;
                    bodyRange.Equip.ShiftVirtualPoint(new Size(0, 0));
                    visLayer.DrawVertex(new Rectangle(this.Location, this.Size), false);
                    SaveVertex();
                    LoadData();
                }
            }
        }

        private void barViewMap_ItemClick(object sender, ItemClickEventArgs e)
        {
            if (_popupRange is BodyRange)
            {
                BodyRange bodyRange = (BodyRange)_popupRange;
                if (bodyRange.Equip != null)
                {
                    switch (bodyRange.Equip.CurveElementKindID)
                    {
                        case 1:
                            _cableToMap(bodyRange.Equip.ID);
                            break;
                        case 2:
                            _vertexToMap();
                            break;
                        case 3:
                            _vertexToMap();
                            break;
                    }
                }
            }
        }

        private void barView_ItemClick(object sender, ItemClickEventArgs e)
        {
            if (!Framework.BaseSecurity.CheckSecurityViewAction()) return;
            if (_popupRange is BodyRange)
            {
                BodyRange bodyRange = (BodyRange)_popupRange;
                if (bodyRange.Equip != null)
                {
                    switch (bodyRange.Equip.CurveElementKindID)
                    {
                        case 1:
                            if (Framework.BaseSecurity.CheckSecurityViewAction())
                            {
                                FrmCables frmCables = FrmCables.ShowForm(false);
                                frmCables.SetActiveCable(bodyRange.Equip.ID);
                            }
                            break;
                        case 2:
                            if (Framework.BaseSecurity.CheckSecurityViewAction())
                            {
                                FrmCableBoxes frmCableBoxes = FrmCableBoxes.ShowForm(false);
                                frmCableBoxes.SetActiveCableBox(bodyRange.Equip.ID);
                            }
                            break;
                        case 3:
                            if (Framework.BaseSecurity.CheckSecurityViewAction())
                            {
                                FrmEquipment frmEquipment = FrmEquipment.ShowForm(false);
                                frmEquipment.SetActiveEquip(bodyRange.Equip.ID);
                            }
                            break;
                    }
                }
            }
        }

        private void _cableToMap(int cableID)
        {
            FrmOpticMap map = FrmOpticMap.ShowForm();
            map.ClearLighted();
            VertexesTableAdapter vertexesTableAdapter = new VertexesTableAdapter();
            vertexesTableAdapter.ClearBeforeFill = true;
            vertexesTableAdapter.SelectCommandTimeout = Properties.Settings.Default.LongQueryTimeout;
            SimpleOpticNetDB.VertexesDataTable vertexesDataTable = vertexesTableAdapter.GetData(null, cableID, null, null,
                                                                                               null, null, null, false, null);
            try
            {
                SimpleOpticNetDB.VertexesRow v =
                    vertexesDataTable.Cast<SimpleOpticNetDB.VertexesRow>().Cast<SimpleOpticNetDB.VertexesRow>().First();

                map.SetCenterMapObject(v.Longitude, v.Latitude);
                foreach (SimpleOpticNetDB.VertexesRow item in vertexesDataTable.Cast<SimpleOpticNetDB.VertexesRow>())
                {
                    map.AddVertesLighted(item.ID);
                }
            }
            catch (Exception)
            {
            }

            CableTunnelsTableAdapter cableTunnelsTableAdapter = new CableTunnelsTableAdapter();
            cableTunnelsTableAdapter.ClearBeforeFill = true;
            cableTunnelsTableAdapter.SelectCommandTimeout = Properties.Settings.Default.LongQueryTimeout;
            SimpleOpticNetDB.CableTunnelsDataTable cableTunnelsDataTable = cableTunnelsTableAdapter.GetData(null, null, null, null, null, null, null, cableID, null);

            foreach (SimpleOpticNetDB.CableTunnelsRow item in cableTunnelsDataTable)
            {
                map.AddCableTunnelLighted(item.ID);
            }
        }

        private void _vertexToMap()
        {
            VertexesTableAdapter vertexesTableAdapter = new VertexesTableAdapter();
            vertexesTableAdapter.ClearBeforeFill = true;
            vertexesTableAdapter.SelectCommandTimeout = Properties.Settings.Default.LongQueryTimeout;
            SimpleOpticNetDB.VertexesDataTable vertexesDataTable = vertexesTableAdapter.GetData(DetailID, null, null, null,
                                                                                               null, null, null, false, null);
            try
            {
                SimpleOpticNetDB.VertexesRow row =
                    vertexesDataTable.Cast<SimpleOpticNetDB.VertexesRow>().Cast<SimpleOpticNetDB.VertexesRow>().First();
                FrmOpticMap map = FrmOpticMap.ShowForm();
                map.SetCenterMapObject(row.Longitude, row.Latitude);
                map.AddVertesLighted(row.ID);
            }
            catch { }


        }

        private void AutoConnect_ItemClick(object sender, ItemClickEventArgs e)
        {
            if (!Framework.BaseSecurity.CheckSecurityTechAction()) return;
            if (!DetailID.HasValue) return;
            if (_popupRange is BodyRange)
            {
                BodyRange bodyRange = (BodyRange)_popupRange;
                if (bodyRange.Equip.CurveElementKindID != 1) return;

                int cabelID = bodyRange.CurveElementID;
                string caption = bodyRange.Caption;
                int? newCurveElementID = new CableBoxList().AddCableBox(DetailID.Value, bodyRange.Equip.Fibres.Count, caption);
                if (!newCurveElementID.HasValue) return;

                visLayer.CreateCableBox(newCurveElementID);
                CrossBoxVis newCurveElement = visLayer.FindCurveElementByID(newCurveElementID.Value);
                newCurveElement.CreateFibre(DetailID.Value);

                foreach (SimpleOpticNetDB.FibreRow item in bodyRange.Equip.Fibres.Cast<SimpleOpticNetDB.FibreRow>())
                {
                    SimpleOpticNetDB.FibreRow fibreRow =
                        (from q in newCurveElement.Fibres.Cast<SimpleOpticNetDB.FibreRow>()
                         where q.Number == item.Number
                         select q).First();

                    if (item.IsToFibre_IDNull() || item.IsToFibre2_IDNull())
                    {
                        new FibrePointList().AddFibrePoint(item.ID, fibreRow.ID, DetailID.Value);
                    }
                }
                if (RefreshVertex != null) RefreshVertex(this, new IntEvent(null));
                visLayer.DrawVertex(new Rectangle(this.Location, this.Size), false);
            }
        }

        private void FibreEdit_ItemClick(object sender, ItemClickEventArgs e)
        {
            if (_popupRange is FibreRange)
            {
                FibreRange fibreRange = (FibreRange)_popupRange;
                if (fibreRange.Row != null)
                    try
                    {
                        FibreList fibreList = new FibreList();
                        fibreList.FibreID = fibreRange.Row.ID;
                        fibreList.DetailID = fibreRange.CurveElementID;
                        fibreList.Present = PresentFormType.InCables;
                        fibreList.AutoEdit();
                        if (RefreshVertex != null) RefreshVertex(this, new IntEvent(null));
                    }
                    catch (Exception)
                    { }
            }
        }

        private void CreateNewSection_ItemClick(object sender, ItemClickEventArgs e)
        {
            if (!Framework.BaseSecurity.CheckSecurityTechAction()) return;
            if (_popupRange is SectionConnectionRange)
            {

                SectionConnectionRange sectionConnectionRange = (SectionConnectionRange)_popupRange;
                sectionConnectionRange.CreateNewSection(visLayer.GetVirtual(StartMovePoint), System.Drawing.Size.Empty);
                visLayer.DrawVertex(new Rectangle(this.Location, this.Size), false);
            }
        }

        private void popup_Popup(object sender, EventArgs e)
        {
            IsPopupShow = true;
        }

        private void popup_CloseUp(object sender, EventArgs e)
        {
            IsPopupShow = false;
            StartMovePoint = Point.Empty;
        }

        private void DeleteSection_ItemClick(object sender, ItemClickEventArgs e)
        {
            if (!Framework.BaseSecurity.CheckSecurityTechAction()) return;
            if (_popupRange is SectionConnectionRange)
            {
                SectionConnectionRange sectionConnectionRange = (SectionConnectionRange)_popupRange;
                if (sectionConnectionRange.StaticPoint == 0)
                {
                    sectionConnectionRange.DeleteSection();
                    visLayer.DrawVertex(new Rectangle(this.Location, this.Size), false);
                }
            }
        }

        private void AddConnectorBox_ItemClick(object sender, ItemClickEventArgs e)
        {
            if (!Framework.BaseSecurity.CheckSecurityTechAction()) return;
            if (DetailID.HasValue)
            {
                new CableBoxList() { CableBoxKind = CableBoxKinds.CableBoxLink }.AddCableBox(DetailID.Value);
                if (RefreshVertex != null) RefreshVertex(this, new IntEvent(null));
                visLayer.DrawVertex(new Rectangle(this.Location, this.Size), false);
            }
        }

        private void ReLine_ItemClick(object sender, ItemClickEventArgs e)
        {
            if (!Framework.BaseSecurity.CheckSecurityTechAction()) return;
            if (_popupRange is BodyRange)
            {
                BodyRange body = (BodyRange)_popupRange;
                if (body.Equip != null && (body.Equip.CurveElementKindID == 2))
                {
                    visLayer.ReCreateConnectorLine(body.Equip.ID);

                    visLayer.DrawVertex(new Rectangle(this.Location, this.Size), false);
                }
            }
        }

        private void FindBreak_ItemClick(object sender, ItemClickEventArgs e)
        {
            if (_popupRange is FibreRange)
            {
                EnterBreak dialog = new EnterBreak();
                DialogResult dlgRes = dialog.ShowModal(BaseModalDetailCtl.ShowModeTypes.Edit);
                try
                {
                    if (dlgRes == DialogResult.OK && dialog.LengthBreak > 0)
                    {
                        FrmOpticMap map = FrmOpticMap.ShowForm();
                        map.ClearLighted();

                        FindCableBreakTableAdapter findCableBreakTableAdapter = new FindCableBreakTableAdapter();
                        findCableBreakTableAdapter.ClearBeforeFill = true;
                        findCableBreakTableAdapter.SelectCommandTimeout = Properties.Settings.Default.LongQueryTimeout;
                        SimpleOpticNetDB.FindCableBreakDataTable findCableBreakDataTable =
                            findCableBreakTableAdapter.GetData(_popupRange.FibreID, DetailID, dialog.LengthBreak, 0);

                        foreach (SimpleOpticNetDB.FindCableBreakRow item in findCableBreakDataTable)
                        {
                            if (item.ComplexID > 0)
                            {
                                map.AddCableTunnelLighted(item.ID);
                                if (item.Length > dialog.LengthBreak)
                                {
                                    double lenBreak = item.Length - dialog.LengthBreak;

                                    CableTunnelsTableAdapter cableTunnelsTableAdapter = new CableTunnelsTableAdapter();
                                    cableTunnelsTableAdapter.ClearBeforeFill = true;
                                    cableTunnelsTableAdapter.SelectCommandTimeout =
                                        Properties.Settings.Default.LongQueryTimeout;
                                    SimpleOpticNetDB.CableTunnelsDataTable cableTunnelTypesDataTable =
                                        cableTunnelsTableAdapter.GetData(item.ID, null, null, null, null, null, null, null, null);
                                    SimpleOpticNetDB.CableTunnelsRow cableTunnelsRow = cableTunnelTypesDataTable[0];

                                    VertexesTableAdapter vertexesTableAdapter = new VertexesTableAdapter();
                                    vertexesTableAdapter.ClearBeforeFill = true;
                                    vertexesTableAdapter.SelectCommandTimeout = Properties.Settings.Default.LongQueryTimeout;
                                    SimpleOpticNetDB.VertexesDataTable vertexesDataTable =
                                        vertexesTableAdapter.GetData(item.VertexID, null, null, null, null, null, null, null,
                                                                     null);
                                    SimpleOpticNetDB.VertexesRow vertexesRow = vertexesDataTable[0];
                                    Coordinate fix = null,
                                               vertex = null,
                                               cableBreak = new Coordinate(vertexesRow.Longitude, vertexesRow.Latitude);
                                    if (vertexesRow.Latitude == cableTunnelsRow.Latitude1 &&
                                        vertexesRow.Longitude == cableTunnelsRow.Longitude1)
                                    {
                                        fix = new Coordinate(vertexesRow.Longitude, vertexesRow.Latitude);
                                        vertex = new Coordinate(cableTunnelsRow.Longitude2, cableTunnelsRow.Latitude2);
                                    }
                                    if (vertexesRow.Latitude == cableTunnelsRow.Latitude2 &&
                                        vertexesRow.Longitude == cableTunnelsRow.Longitude2)
                                    {
                                        fix = new Coordinate(vertexesRow.Longitude, vertexesRow.Latitude);
                                        vertex = new Coordinate(cableTunnelsRow.Longitude1, cableTunnelsRow.Latitude1);
                                    }
                                    if (fix != null && vertex != null)
                                    {
                                        double len = fix.Distance(vertex);
                                        double l = len / lenBreak;
                                        cableBreak.Latitude = fix.Latitude + (vertex.Latitude - fix.Latitude) / l;
                                        cableBreak.Longitude = fix.Longitude + (vertex.Longitude - fix.Longitude) / l;
                                        if (!item.IsComplex || item.IsComplexIDNull())
                                        {
                                            map.AddFreeLine(new NetLayer.FreeLine()
                                                                {
                                                                    Color = Color.Blue,
                                                                    Width = 2,
                                                                    TunnelRect = new CoordinateRectangle(fix, cableBreak)
                                                                });
                                            map.AddMapPoint(cableBreak);
                                            map.SetCenterMapObject((decimal)cableBreak.Longitude,
                                                                   (decimal)cableBreak.Latitude);
                                        }


                                    }
                                }
                                else
                                {

                                }
                            }
                            if (item.ComplexID == 0) map.AddVertesLighted(item.ID);
                        }
                    }
                }
                catch(Exception error)
                { XtraMessageBox.Show(error.Message, "Сообщение", MessageBoxButtons.OK, MessageBoxIcon.Warning); }
            }
        }

        private void ReMakeLines_ItemClick(object sender, ItemClickEventArgs e)
        {
            DeleteLine();
            switch (visLayer.PlanType)
            {
                case 3:
                    LoadElement(ExtendedPropertieTypes.VertexConnectionLineAll, true);
                    break;
                case 2:
                    LoadElement(ExtendedPropertieTypes.VertexConnectionLineOnlyCableBox, true);
                    break;
                case 1:
                    LoadElement(ExtendedPropertieTypes.VertexConnectionLineOnlyCable, true);
                    break;
            }

            if (RefreshVertex != null) RefreshVertex(this, new IntEvent(null));
            visLayer.DrawVertex(new Rectangle(this.Location, this.Size), false);
        }
    }
}
